php5 용입니다.
예외 처리: 클래스 안에서 모두 처리.
원 소스:
class DB_Mysql {
protected $user;
protected $pass;
protected $dbhost;
protected $dbname;
protected $dbh; // Database connection handle.
protected $exception;
public function __construct($user, $pass, $dbhost, $dbname, $exception = "MysqlException") {
$this->user = $user;
$this->pass = $pass;
$this->dbhost = $dbhost;
$this->dbname = $dbname;
$this->exception = $exception;
}
protected function connect() {
$this->dbh = @mysql_connect($this->dbhost, $this->user, $this->pass);
if(!is_resource($this->dbh)) {
throw new $this->exception("Error establishing a database connection");
}
if(!@mysql_select_db($this->dbname, $this->dbh)) {
throw new $this->exception("Can’t select database, Please check DB, username, password.");
}
}
public function execute($query) {
try {
if(!$this->dbh) {
$this->connect();
}
$ret = mysql_query($query, $this->dbh);
if(!$ret) {
throw new $this->exception;
}
if(!is_resource($ret)) {
return true;
}
else {
$stmt = new DB_MysqlStatement($this->dbh, $query, $this->exception);
$stmt->result = $ret;
return $stmt;
}
} catch (MysqlException $e) {
$e->displayError();
exit;
}
}
public function prepare($query) {
try {
if(!$this->dbh) {
$this->connect();
}
return new DB_MysqlStatement($this->dbh, $query, $this->exception);
} catch (MysqlException $e) {
$e->displayError();
exit;
}
}
};
// Wrapper for mysql return value resource,
// resource will be returned back to the DB_Mysql.
class DB_MysqlStatement {
public $affected_rows;
public $result;
public $binds;
public $query;
public $retval;
protected $dbh;
protected $exception;
public function __construct($dbh, $query, $exception) {
$this->query = $query;
$this->dbh = $dbh;
$this->exception = $exception;
if(!is_resource($dbh)) {
throw new $this->exception("Not a valid database connection");
}
}
// A bit faster.
public function fetch_row() {
if(!$this->result) {
throw new $this->exception("Query not executed");
}
return mysql_fetch_row($this->result);
}
private function fetch_obj() {
if(!$this->result) {
throw new $this->exception("Query not executed");
}
return mysql_fetch_object($this->result);
}
private function fetch_array() {
if(!$this->result) {
throw new $this->exception("Query not executed");
}
return mysql_fetch_array($this->result, MYSQL_ASSOC);
}
// Fetch all.
private function fetchall_array() {
while($row = $this->fetch_array()) {
$this->retval[] = $row;
}
return $this->retval;
}
private function fetchall_obj() {
while($row = $this->fetch_obj()) {
$this->retval[] = $row;
}
return $this->retval;
}
public function execute() {
try {
$this->_flush();
$binds = func_get_args();
foreach($binds as $index => $name) {
$this->binds[$index+1] = $name;
}
$cnt = count($binds);
$query = $this->query;
if($this->binds) {
foreach($this->binds as $ph => $pv) {
// Escape the string.
$query = str_replace(":$ph", "'".mysql_real_escape_string($pv)."'", $query);
}
}
$this->result = mysql_query($query, $this->dbh);
if(!$this->result) {
throw new $this->exception;
}
if(!is_resource($this->result)) { // insert|update|delete|replae, not enough?
//return the count of affected rows.
return $this->affected_rows = mysql_affected_rows($this->dbh);
}
return $this;
} catch (MysqlException $e) {
$e->displayError();
exit;
}
}
public function get_all($obj = "") {
try {
if($obj == "")
return $this->fetchall_obj();
else if($obj == "array")
return $this->fetchall_array();
} catch (MysqlException $e) {
$e->displayError();
}
}
// get one row.
// this function also check whether there is no result.
public function get_row($obj = "") {
try {
if($obj == "")
return $this->fetch_obj();
else if($obj == "array")
return $this->fetch_array();
} catch (MysqlException $e) {
$e->displayError();
}
}
// get one val.
public function get_var() {
try {
$val = $this->fetch_row();
return $val[0];
} catch (MysqlException $e) {
$e->displayError();
}
}
public function _flush() {
$this->result = null;
}
};
사용 예:
define('DB_USER', 'intranet');
define('DB_PASS', 'intranet04');
define('DB_HOST', 'localhost');
define('DB_NAME', 'intranet');
define('SHOWERROR', TRUE); // 거짓일 경우 에러 출력되지 않고 로그 파일로 처리.
define('dbErrorPath', ABSPATH . 'logs/dberror.log');
$db = new DB_Mysql;
$query = "SELECT name from users WHERE login_id in (:1, :2) ";
$result = $db->prepare($query)->execute("admin", "d")->get_all();
$result = $db->prepare($query)->execute("admin", "d")->get_row();
$result = $db->prepare($query)->execute("admin", "d")->get_var();
echo "<pre>";
print_r($result);
ERROR HANDLER.
/**
* Exeption handling class for DB_Mysql
* @output: error(), errno();
* Date: May 2006
*
* Basic Exception structure in Zend
* public function __construct($message=false, $code=false) {
* $this->file = __FILE__;
* $this->line = __LINE__;
* $this->message = $message;
* $this->code = $code;
* }
*
*/
class MysqlException extends Exception {
protected $backtrace;
public function __construct($message=false, $code=false) {
if(!$message) {
$this->message = mysql_error();
} else {
$this->message = $message;
}
if(!$code) {
$this->code = mysql_errno();
} else {
$this->code = $code;
}
$this->backtrace = debug_backtrace();
}
public function displayError() {
if(SHOWERROR) {
//elcCoreApi::bypass_header();
$this->DBerrorPage();
} else {
// Append this to a log file.
$log_msg = $this->_error_log();
$this->appendToLog($log_msg);
}
}
// log errors
public function _error_log() {
unset($this->backtrace);
ob_start();
echo "********** DB Error: ".$_SERVER['SCRIPT_NAME']." **********\n\n";
print_r($this);
echo "********** Date: ".date('m-d-Y H:i:s')." **********\n\n";
$output = ob_get_contents();
ob_end_clean();
return $output;
}
public function appendToLog($log = "") {
if(defined('dbErrorPath')):
// check the dir first, if not create.
// file based log.
Upload::dir_Check(dirname(dbErrorPath));
@error_log($log, 3, dbErrorPath);
else:
@error_log($log, 3, 'dberror.log');
endif;
}
// Default DB error page.
public function DBerrorPage() {
$charset = charset;
echo <<<HEAD
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Database › Error</title>
<meta http-equiv="Content-Type" content="text/html; charset=$charset" />
<style media="screen" type="text/css">
<!--
html {
background: #eee;
}
body {
background: #fff;
color: #000;
font-family: Verdana, "Times New Roman", Times, serif;
font-size: 12px;
}
#infldset {
padding-left: 8px;
}
-->
</style>
</head>
<body>
<div align="left">
<fieldset><legend> Database Error! </legend>
<br />
<div id="infldset">
HEAD;
foreach($this as $field_name => $error_val) {
if($field_name != backtrace)
echo strtoupper($field_name).": ". $error_val."<br />";
}
echo "<br />-- Backtrace a file with an array set --";
echo "<pre>";
print_r($this->backtrace[1]);
echo "</pre>";
echo <<<END
</div>
</fieldset>
</div>
</body><html>
END;
exit;
}
};
extends 시: 템프릿 패턴.
원하는 방식으로 예외 처리 가능.
$db = new DB_Mysql_production_site;
class DB_Mysql_production_site extends DB_Mysql {
protected $user = DB_USER;
protected $pass = DB_PASS;
protected $dbhost = DB_HOST;
protected $dbname = DB_NAME;
protected $exception = "MysqlException_production_site";
public function __construct() {
// Empty.
}
};
class MysqlException_production_site extends MysqlException {
public function displayError() {
if(SHOWERROR) {
$this->DBerrorPage();
} else {
// Append this to a log file.
$log_msg = $this->_error_log();
$this->appendToLog($log_msg);
}
}
// Default DB error page.
public function DBerrorPage() {
$charset = charset;
echo <<<HEAD
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Production site database › Error</title>
<meta http-equiv="Content-Type" content="text/html; charset=$charset" />
<style media="screen" type="text/css">
<!--
html {
background: #eee;
}
body {
background: #fff;
color: #000;
font-family: Verdana, "Times New Roman", Times, serif;
font-size: 12px;
}
#infldset {
padding-left: 8px;
}
-->
</style>
</head>
<body>
<div align="left">
<fieldset><legend> Production site database Error! </legend>
<br />
<div id="infldset">
HEAD;
foreach($this as $field_name => $error_val) {
if($field_name != backtrace)
echo strtoupper($field_name).": ". $error_val."<br />";
}
echo "<br />-- Backtrace a file with an array set --";
echo "<pre>";
print_r($this->backtrace[1]);
echo "</pre>";
echo <<<END
</div>
</fieldset>
</div>
</body><html>
END;
exit;
}
};
업로드 클래스(PHP4)
예전에 만든것이라 PHP5 용은 없습니다.
**
* For file uploading.
* Just Create new instance with $_FILES, that's it.
* Multiple, single upload OK.
* @return array_object (ex. if single, print $upload->name, if multiple, echo $upload->size[1]
*
* Constructor could make the file's file name and extension separately.
* $upload->file_ext[0], $upload->file_name[0].
*/
사용예:
$up = new Upload($_FILES);
$up->file_Upload("../upload_path"); // Upload now
class Upload {
var $name;
var $tmp_name;
var $size;
var $error;
var $file_name = array();
var $file_ext = array();
var $key;
var $val;
var $f_key;
var $f_val;
var $randId;
var $rtn_val;
function Upload($FILES = "") {
if($FILES && count($FILES) > 0) {
foreach($FILES as $this->key => $this->val){
foreach($this->val as $this->f_key => $this->f_val) {
if($this->f_key == 'name') {
$this->name = $this->f_val;
// Get a file's file name and its extension.
foreach($this->name as $i => $v) {
$this->file_name[$i] = substr($this->name[$i], 0, strrpos($this->name[$i], "."));
$this->file_ext[$i] = substr(strrchr($this->name[$i], "."), 1);
}
} else if($this->f_key == 'type') {
$this->type = $this->f_val;
} else if($this->f_key == 'tmp_name') {
$this->tmp_name = $this->f_val;
} else if($this->f_key == 'size') {
$this->size = $this->f_val;
} else {
$this->error = $this->f_val;
}
}
}
} else {
// Empty.
}
}
function file_Upload($dir = "") {
$dest_dir = ($dir) ? $dir : "file_tmp";
$save_dir = $this->dir_Check($dest_dir);
foreach($this->name as $i => $v) {
if($this->name[$i] != "" || strlen($this->name[$i]) > 0) { // More secure.
$dest = $save_dir.$this->name[$i];
$file_exist = $this->is_File_Exists($dest);
if(!$file_exist) {
if(!copy($this->tmp_name[$i], $dest)) {
die("Error, can not upload the files, Please check the dir's permission or wrong dir's name");
}
} else { // If same file name, create a filename_randnum.ext
$rand = $this->get_RandID(5);
$new_dest = $save_dir.$this->file_name[$i]."_".$rand.".".$this->file_ext[$i];
if(!copy($this->tmp_name[$i], $new_dest)) {
die("Error, can not upload the files, Please check the dir's permission or wrong dir's name(duplicate)");
}
}
}
}
}
// Function to get a file name and extension.
// But constructor will be giving this without call this function again.
// Just leave here. Sometimes we need an extension in somewhere without constructor.
function get_fileName($filename) {
$this->file_name = substr($filename, 0, strrpos($filename, "."));
$this->file_ext = substr(strrchr($filename, "."), 1);
$rtn_val = array($this->file_name, $this->file_ext);
return $rtn_val;
}
// @return true
function is_filename_exist($file) {
if(isset($file) && strlen($file) > 0)
return true;
}
// Check the valid extension given by $current_ext.
function is_valid_ext($current_ext, $valid_ext) {
if(is_array($valid_ext) && count($valid_ext) > 0) { // If array of extension (ex. $valid_ext=array("pdf","jpg")).
foreach($valid_ext as $key => $val) {
if($current_ext != $val) {
return false;
} else {
return true;
}
}
} else { // Single value.
if($current_ext != $valid_ext) {
return false;
} else {
return true;
}
}
}
// If same file name exists.
function is_File_Exists($up_file) {
return is_file($up_file);
}
function del_File($filepath) {
if(is_file($filepath)) {
if(!unlink($filepath))
die("Can not delete the file, check to see if file exists");
}
}
function copy_File($filepath, $dest) {
if(is_file($filepath)) {
if(!copy($filepath, $dest)) {
die("Error, can not upload the files, Please check the dir's permission or wrong dir's name - copy file.");
}
}
}
// If there is no such a dir then create the directory.
function dir_Check($path) {
if(!(is_dir($path) )){
$path_temp = split("/",$path);
for ($i = 0 ; $i < count($path_temp) ; $i++ ){
$path_str .= trim($path_temp[$i])."/";
if(!(is_dir($path_str) )){
@mkdir($path_str, 0777 );
@chmod($path_str, 0777 );
}
}
return $path_str;
}
$path .= "/";
return $path;
}
// Copy a folder with its all files to the specified folder.
function dir_Copy($src_path, $dest_path) {
$this->dir_Check($dest_path); // Create dir.
// Copy all files in the folder now.
if(is_dir($src_path)) {
if($dir = @opendir($src_path)) {
while (($file = @readdir($dir)) !== false) {
if($file != "." && $file != "..") {
if(is_dir($src_path)."/".$file) {
if(is_dir($dest_path)) {
if(!copy($src_path."/".$file, $dest_path."/".$file)) {
die("Error, can not upload the files, Please check the dir's permission or wrong dir's name - copy dir.");
}
}
}
}
}
closedir($dir);
}
}
}
// rename the folder.
function dir_Rename($path, $newpath) {
return @rename($path, $newpath);
}
// Delete the directory and its all files as well.
// Must be careful this function will delete all dirs and all files.
function dir_Del($path) {
if(is_dir($path)){
if($dir = @opendir($path)) {
while (($file = readdir($dir)) !== false) {
if($file != "." && $file != ".." ){
if(is_dir($path."/".$file)){
$this->dir_Del($path."/".$file);
}else{
unlink($path."/".$file);
}
}
}
closedir($dir);
}
rmdir($path);
}
}
// Prevent duplicated file name, add this if need..
function get_RandID($length = "") {
$uid = md5(uniqid(rand()));
if($length != "" && $length > 32)
$length = 32;
else if($length == "")
$length = 32;
else
$length;
$this->randId = substr($uid,0,$length);
return $this->randId;
}
// Get only file name from whole directory path, we could use the basename though.
function get_Basename($fullpath, $separator) {
if($this->is_File_Exists($fullpath)){
$filename = substr(strrchr($fullpath, $separator), 1);
return $filename;
}
}
};
License
본 게시물은 GPL을 따릅니다. [ GPL 안내 ]
앤죠 06-05-18 14:32
몇년전 PHP4 용으로 만들어논 클래스들이 있는데 윗들을보니 많이 발전했네요.
PHP4 때서는 되는게 상속밖에 없어서 업무별로 상속받아서 했었는데
이젠 반쪽짜리 에서 제대로 자리를 잡아가는것 같습니다.
일단 try catch 가 된다는게 무지 방갑고ㅋ
변수 선언시 public, ptotected, private 으로 명확하게 해준다는거소 맘에 들고,
혹시 오버로딩도 되는지...
2년 전부터 닷넷쪽으로 하다보니 PHP가 새삼 많이 발전했다는걸 느낍니다.
몇년전 PHP4 용으로 만들어논 클래스들이 있는데 윗들을보니 많이 발전했네요.
PHP4 때서는 되는게 상속밖에 없어서 업무별로 상속받아서 했었는데
이젠 반쪽짜리 에서 제대로 자리를 잡아가는것 같습니다.
일단 try catch 가 된다는게 무지 방갑고ㅋ
변수 선언시 public, ptotected, private 으로 명확하게 해준다는거소 맘에 들고,
혹시 오버로딩도 되는지...
2년 전부터 닷넷쪽으로 하다보니 PHP가 새삼 많이 발전했다는걸 느낍니다.
괴부기 06-05-18 16:05
오버로딩은 여전히 __get() 과 __set() 외에는 개인적으로 지원되지 않습니다.
오버라이딩이 최선의 선택이지만, 내부적으로 엄청난 변화가 있기에 이제는 PHP로 자바와 같은
프레임워크 구성도 가능하지요.
왠만한 패턴 방식은 다 구현이 가능합니다
오버로딩은 여전히 __get() 과 __set() 외에는 개인적으로 지원되지 않습니다.
오버라이딩이 최선의 선택이지만, 내부적으로 엄청난 변화가 있기에 이제는 PHP로 자바와 같은
프레임워크 구성도 가능하지요.
왠만한 패턴 방식은 다 구현이 가능합니다
괴부기 06-05-18 16:18
질문!
http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=qna_function&wr_id=141010
아시는 님은 샘플이라도.. 궁금해서 미칠 지경..
질문!
http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=qna_function&wr_id=141010
아시는 님은 샘플이라도.. 궁금해서 미칠 지경..
lkm_plus 07-03-06 18:39
Warning: Missing argument 1 for DB_Mysql::__construct(), called in /var/www/wizard/class/dbClass.php on line 200 and defined in /var/www/wizard/class/dbClass.php on line 10
Warning: Missing argument 2 for DB_Mysql::__construct(), called in /var/www/wizard/class/dbClass.php on line 200 and defined in /var/www/wizard/class/dbClass.php on line 10
Warning: Missing argument 3 for DB_Mysql::__construct(), called in /var/www/wizard/class/dbClass.php on line 200 and defined in /var/www/wizard/class/dbClass.php on line 10
Warning: Missing argument 4 for DB_Mysql::__construct(), called in /var/www/wizard/class/dbClass.php on line 200 and defined in /var/www/wizard/class/dbClass.php on line 10
이 에러가 나는 원인은 뭘까요..
출처 : http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=46267&sca=&sfl=wr_subject%7C%7Cwr_content&stx=php5&sop=and&page=4 |